package com.lintf.bot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lintf.bot.domain.BotConsumption;
import com.lintf.bot.domain.BotMoney;
import com.lintf.bot.domain.dto.BotConsumptionAddDTO;
import com.lintf.bot.domain.dto.BotConsumptionListDTO;
import com.lintf.bot.domain.dto.BotConsumptionRemoveDTO;
import com.lintf.bot.domain.dto.BotConsumptionUpdateDTO;
import com.lintf.bot.domain.enums.ConsumptionTypeEnums;
import com.lintf.bot.mapper.BotConsumptionMapper;
import com.lintf.bot.service.IBotConsumptionService;
import com.lintf.bot.service.IBotMoneyService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * @author lintf
 * @description 针对表【bot_consumption】的数据库操作Service实现
 * @createDate 2024-01-09 15:42:31
 */
@Service
public class BotConsumptionServiceImpl extends ServiceImpl<BotConsumptionMapper, BotConsumption>
        implements IBotConsumptionService {

    @Autowired
    private IBotMoneyService botMoneyService;

    @Override
    public List<BotConsumption> list(BotConsumptionListDTO dto) {
        LocalDateTime startDate = LocalDateTime.parse(dto.getDateSearchValue() + "-01 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        LocalDateTime endDate = startDate.plusMonths(1); // 结束日期为开始日期的下个月
        LambdaQueryWrapper<BotConsumption> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BotConsumption::getBotMoneyId, dto.getBotMoneyId())
                .ge(BotConsumption::getCreateTime, startDate)
                .lt(BotConsumption::getCreateTime, endDate)
                .orderByDesc(BotConsumption::getCreateTime);
        return baseMapper.selectList(wrapper);
    }

    /**
     * 更新消费信息
     *
     * @param dto 消费更新DTO
     * @return 更新结果
     */
    @Override
    @Transactional
    public int add(BotConsumptionAddDTO dto) {
        // 创建Bot消费对象
        BotConsumption botConsumption = new BotConsumption();
        // 将DTO属性复制到Bot消费对象
        BeanUtils.copyProperties(dto, botConsumption);
        // 设置创建参数
//        botConsumption.setCreateParams();
        // 获取对应Bot账户信息
        BotMoney botMoney = botMoneyService.getById(dto.getBotMoneyId());
        BigDecimal balanceTotal = botMoney.getBalanceTotal();
        // 如果更新金额为空
        if (dto.getUpdateMoney() == null) {
            // 扣除消费总额
            balanceTotal = balanceTotal.subtract(dto.getConsumptionTotal());
            botConsumption.setConsumptionBalance(balanceTotal);
        } else {
            // 增加更新金额
            balanceTotal = balanceTotal.add(dto.getUpdateMoney());
            botConsumption.setConsumptionType(ConsumptionTypeEnums.EXPENDITURE.getValue());
            botConsumption.setConsumptionBalance(balanceTotal);
            // 更新Bot账户总金额
            botMoney.setMoneyTotal(botMoney.getMoneyTotal().add(dto.getUpdateMoney()));
        }
        // 更新Bot账户余额
        botMoney.setBalanceTotal(balanceTotal);
        botMoneyService.updateById(botMoney);
        // 插入Bot消费记录
        baseMapper.insert(botConsumption);
        return 1;
    }

    /**
     * 更新消费信息
     *
     * @param dto 消费更新DTO
     * @return 更新结果
     */
    @Override
    public int update(BotConsumptionUpdateDTO dto) {
        // 根据ID查询消费信息
        BotConsumption consumption = baseMapper.selectById(dto.getId());
        BigDecimal consumptionBalance = consumption.getConsumptionBalance();
        BigDecimal consumptionTotal = consumption.getConsumptionTotal();
        // 构建更新条件
        LambdaUpdateWrapper<BotMoney> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(BotMoney::getId, consumption.getBotMoneyId());
        BotMoney botMoney = new BotMoney();
        BigDecimal decimal;
        // 根据消费类型更新余额
        if (consumption.getConsumptionType() == ConsumptionTypeEnums.INCOME.getValue()) {
            BigDecimal balance = consumptionBalance.add(consumptionTotal);
            consumption.setConsumptionTotal(dto.getConsumptionTotal());
            BigDecimal subtract = balance.subtract(dto.getConsumptionTotal());
            decimal = subtract;
            consumption.setConsumptionBalance(subtract);
        } else {
            BigDecimal balance = consumptionBalance.subtract(consumptionTotal);
            consumption.setConsumptionTotal(dto.getConsumptionTotal());
            BigDecimal add = balance.add(dto.getConsumptionTotal());
            decimal = add;
            consumption.setConsumptionBalance(add);
        }
        // 更新余额信息
        botMoney.setBalanceTotal(decimal);
        consumption.setConsumptionTitle(dto.getConsumptionTitle());
        // 更新消费信息
        int updated = baseMapper.updateById(consumption);
        // 更新余额信息
        if (botMoneyService.update(botMoney, updateWrapper)) {
            return updated;
        }
        return 0;
    }

    @Override
    @Transactional
    public int remove(BotConsumptionRemoveDTO dto) {
        BotConsumption consumption = baseMapper.selectById(dto.getId());
        BigDecimal consumptionBalance = consumption.getConsumptionBalance();
        BigDecimal consumptionTotal = consumption.getConsumptionTotal();
        BigDecimal decimal;
        if (dto.getConsumptionType() == ConsumptionTypeEnums.INCOME.getValue()) {
            decimal = consumptionBalance.add(consumptionTotal);
        } else {
            decimal = consumptionBalance.subtract(consumptionTotal);
        }
        LambdaUpdateWrapper<BotMoney> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(BotMoney::getId, consumption.getBotMoneyId());
        BotMoney botMoney = new BotMoney();
        botMoney.setBalanceTotal(decimal);
        botMoneyService.update(botMoney, updateWrapper);
        baseMapper.deleteById(dto.getId());
        return 1;
    }
}




